package com.dingpeikeji.quickdeer.mobile.service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alipay.api.RefundFastpayByPlatformNopwdApi;
import com.alipay.model.RefundFastpayByPlatformNopwdReq;
import com.dingpeikeji.quickdeer.core.common.persistence.Page;
import com.dingpeikeji.quickdeer.core.modules.cupons.entity.CuponsInfo;
import com.dingpeikeji.quickdeer.core.modules.cupons.service.TCuponsService;
import com.dingpeikeji.quickdeer.core.modules.orders.entity.TOrders;
import com.dingpeikeji.quickdeer.core.modules.orders.entity.TOrdersOut;
import com.dingpeikeji.quickdeer.core.modules.orders.service.TOrdersOutService;
import com.dingpeikeji.quickdeer.core.modules.orders.service.TOrdersService;
import com.dingpeikeji.quickdeer.core.modules.payinfo.entity.TPayinfo;
import com.dingpeikeji.quickdeer.core.modules.realsche.entity.TRealsche;
import com.dingpeikeji.quickdeer.core.modules.realsche.service.TRealscheService;
import com.dingpeikeji.quickdeer.core.modules.sys.entity.Office;
import com.dingpeikeji.quickdeer.core.modules.sys.entity.User;
import com.dingpeikeji.quickdeer.core.modules.sys.utils.UserUtils;
import com.dingpeikeji.quickdeer.mobile.entity.CitySceneryInfo;
import com.dingpeikeji.quickdeer.mobile.entity.DestinationInfo;
import com.dingpeikeji.quickdeer.mobile.entity.TripCounselorInfo;
import com.dingpeikeji.quickdeer.modules.base.service.FrontUserService;
import com.dingpeikeji.quickdeer.modules.base.web.FSysController;
import com.dingpeikeji.quickdeer.modules.realsche.service.FRealscheService;
import com.dingpeikeji.quickdeer.modules.rentproduct.entity.DemandsReact;
import com.dingpeikeji.quickdeer.modules.rentproduct.entity.ShareRentproduct;
import com.dingpeikeji.quickdeer.modules.rentproduct.entity.TDemands;
import com.dingpeikeji.quickdeer.modules.rentproduct.service.FDemandsService;
import com.dingpeikeji.quickdeer.modules.rentproduct.service.ShareProductService;
import com.dingpeikeji.quickdeer.modules.sms.entity.Sms;
import com.dingpeikeji.quickdeer.modules.sms.service.SmsApi;
import com.dingpeikeji.quickdeer.utils.BackResult;
import com.dingpeikeji.quickdeer.utils.CookieUtils;
import com.google.common.collect.Lists;
import com.tencent.WXPay;
import com.tencent.common.Configure;
import com.tencent.protocol.refund_protocol.RefundReqData;

@Service
@Transactional(readOnly = true)
public class MobileOrderService {
	@Autowired
	private FRealscheService fRealscheService;
	@Autowired
	private TOrdersService tOrdersService;
	@Autowired
	private ShareProductService shareProductService;
	@Autowired
	private FDemandsService demandsService;
	@Autowired
	private TRealscheService tRealscheService;
	@Autowired
	private FrontUserService frontUserService;
	@Autowired
	private TOrdersOutService tOrdersOutService;
	@Autowired
	private TripCounselorService tripCounselorService;
	@Autowired
	private CitySceneryService citySceneryService;
	@Autowired
	private DestinationService destinationService;
	@Autowired
	private TCuponsService tCuponsService;
	
	protected Logger logger = LoggerFactory.getLogger(getClass());

	public BackResult getOrderList(TOrders orders, HttpServletRequest request, HttpServletResponse response) throws Exception {
		Map<String,Object> map = new HashMap<String, Object>();
		// 当前订票人
		User user = frontUserService.get(request.getParameter("userid"));
		if (user==null) {
			return BackResult.build("400", "获取用户信息失败");
		}
		orders.setOrderuserid(user.getId());
		Page<TOrders> page = new Page<TOrders>(request, response);
		//每页多少条数据
		int pageSize = Integer.parseInt(request.getParameter("pageSize"));
		page.setPageSize(pageSize);
		//当前第几页
		int pageNo = Integer.parseInt(request.getParameter("pageNo"));
		page.setPageNo(pageNo);
		page = fRealscheService.findOrderPageForMobile(new Page<TOrders>(request, response), orders);
		if (page.getCount()==0) {
			return BackResult.build("400", "未查询到订单数据");
		}
		int pageCount = (int) Math.ceil(page.getCount()*1.0/pageSize);
		map.put("pageCount", pageCount);
		if (pageNo>pageCount) {
			return BackResult.build("401", "没有更多数据");
		}
		map.put("ordersList", page.getList());
		map.put("totalCount", page.getCount());
		
		return BackResult.ok(map);
	}
	public BackResult getOrderDetail(TOrders orders,HttpServletRequest request) {
		Map<String,Object> map = new HashMap<String, Object>();
		orders = fRealscheService.getOrders(orders.getOrderid());
		if (orders==null) {
			return BackResult.build("400", "未查询到数据");
		}
		//AA拼车
		if (TOrders.ORDER_TYPE_TRAVEL_SHARE.equals(orders.getOrdertype())||TOrders.ORDER_TYPE_AIR_SHARE.equals(orders.getOrdertype())) {
			ShareRentproduct shareRentproduct = shareProductService.getInfo(orders.getShareid());
			if (shareRentproduct!=null ) {
				map.put("minamount", shareRentproduct.getMinamount());
				map.put("endTime", shareRentproduct.getEnddate());
				map.put("currentsell", shareRentproduct.getCurrentsell());
			}
		}
		if(orders.getOrdertype().equals(TOrders.ORDER_TYPE_RENTPRODUCT_CUSTOM) && !orders.getOrderstatus().equals(TOrders.STATUS_BACK) && !orders.getOrderstatus().equals(TOrders.STATUS_CANCEL)) {
			TRealsche realsche = tRealscheService.get(orders.getRealscheid());
			if(realsche!=null){
				DemandsReact react = demandsService.getDemandsReact(Integer.parseInt(realsche.getScheid()));
				TDemands tDemands = demandsService.getDemandById(react.getDemandid());
				map.put("react", react);
				map.put("tDemands", tDemands);
			}
		}//如果是行程顾问订单
		if(orders.getOrdertype().equals("9")){
			TripCounselorInfo tripCounselorInfo=tripCounselorService.getTripByOrderId(orders.getOrderid());
				String tripId=tripCounselorInfo.getTripCounselorId();//根据tripId去查找该次行程的目的地和必游景点
				String[] name=destinationService.getDestinationList(tripId);
				String place="",city="";
				for(int j=0;j<name.length;j++){
					DestinationInfo d=new DestinationInfo();
					d.setDestination(name[j]);
					city=city+name[j];
					if(j<name.length-1){
						city=city+",";
					}
					tripCounselorInfo.getDestination().add(d);
				}
				String[] name2=citySceneryService.getCitySceneryListByTripId(tripId);
				
				for(int j=0;j<name2.length;j++){
					CitySceneryInfo c =new CitySceneryInfo();
					c.setSceneryName(name2[j]);
					if(name2[j]==null||name2[j].equals("")){
						place="不限";
					}else{
						place=place+name2[j];
					}
					if(j<name2.length-1){
						place=place+",";
					}
					tripCounselorInfo.getCityScenery().add(c);
				}
				if(tripCounselorInfo.getPayState().equals("1")){
					if(tripCounselorService.getTripPreviewList(tripCounselorInfo.getTripCounselorId())!=null&&tripCounselorService.getTripPreviewList(tripCounselorInfo.getTripCounselorId()).size()>0&&tripCounselorService.getTripPreviewList(tripCounselorInfo.getTripCounselorId()).get(0).getIsDisable().equals("1")){
						String url="https://www.xiakeyueche.com/f/mobile/preview?tripCounselorId=";
						map.put("url", url+tripCounselorInfo.getTripCounselorId());
					}else{
						map.put("url", "");
					}
				}
				map.put("city", city);
				map.put("place", place);
				map.put("tripCounselorInfo",tripCounselorInfo);
		}else{
			if(orders.getCartype()!=null){
				map.put("cargotype", orders.getCartype());
			}
		}
		if(orders.getUseCupons().equals("1")){
			CuponsInfo info=tCuponsService.getRecordByOrderId(orders.getOrderid());
			if(info!=null)
			map.put("cuponsInfo", info);
		}
		map.put("orders", orders);
		return BackResult.ok(map);
	}
	public BackResult cancelOrder(TOrders orders){
		String cancelid = null; // 取消人ID
		TOrders ord=tOrdersService.get(orders.getOrderid());
		if(!ord.getOrderstatus().equals(TOrders.STATUS_NO_PAY)) {
			return BackResult.build("400", "该订单不能取消");
		} else {
			String message = fRealscheService.cancelOrder(orders, cancelid);//如果订单是行程顾问则还要修改行程表中状态
			if(tOrdersService.get(orders.getOrderid()).getOrdertype().equals("9")){
				tripCounselorService.updateTripState(orders.getOrderid(),TOrders.STATUS_BACK);
			}
			if(message == null){
				if(ord.getUseCupons().equals("1")){//如果取消的订单使用了优惠券 则重新发放
					CuponsInfo record =tCuponsService.getRecordByOrderId(orders.getOrderid());
					if(record.getCuponsId().equals("e3c7b1b6a6044d0994d3aeb0e3d55088")){
						tCuponsService.registCupons(ord.getOrderuserid());
					}else{
						tCuponsService.aaCarCupons(ord.getOrderuserid());
					}
				}
				return BackResult.build("200", "取消订单成功！");
			}  else {
				return BackResult.build("200", message);
			}
		}
	}
	public BackResult toBackMoneyPage(HttpServletRequest request) throws Exception{
		Map<String, Object> map = new HashMap<String, Object>();
		String orderid = request.getParameter("orderid");
		TOrders torders = fRealscheService.getOrders(orderid);
		if (torders.getDepartdate().before( new Date())) {
			return BackResult.build("400", "已过发车时间,无法退单");
		}
		User user = frontUserService.get(request.getParameter("userid"));
		if (user==null) {
			return BackResult.build("400", "获取用户信息失败");
		}
		if (!TOrders.STATUS_PAY.equals(torders.getOrderstatus())) {
			return BackResult.build("400", "已支付订单才可以退单");
		}
		//AA拼车,已经超过截止时间,无法退单
		if (TOrders.ORDER_TYPE_TRAVEL_SHARE.equals(torders.getOrdertype())||TOrders.ORDER_TYPE_AIR_SHARE.equals(torders.getOrdertype())) {
			ShareRentproduct shareRentproduct = shareProductService.getInfo(torders.getShareid());
			if("1".equals(shareRentproduct.getIssuccess())){
				return BackResult.build("400", "拼车已成功,无法退单");
			}
			if (shareRentproduct.getEnddate().before(new Date())) {
				return BackResult.build("400", "拼车已截止,无法退单");
			}
			map.put("dueamount", torders.getDueamount());
			map.put("penalty", "0");
			return BackResult.ok(map);
		}else {
			//计算时间差
			long dateDistance = getDatePoor(torders.getDepartdate(), new Date());
			//计算违约金
			double penalty = 0.0;
			if (dateDistance<=24) {
				//行程开始前 24 小时内,按费用总额的50%收取违约金
				penalty = Math.ceil(Double.parseDouble(torders.getDueamount())*0.5);
			}else if (dateDistance<=0) {
				//超过发车时间不可退款
				penalty = Math.ceil(Double.parseDouble(torders.getDueamount()));
			}else if(dateDistance<=72&&dateDistance>24){
				//行程开始前 72 小时至 24 小时,按费用总额的30%(普通用户)
				if (Office.FLAT_TYPE_SMALLCO.equals(user.getOffice().getFlatType())) {
					penalty = Math.ceil(Double.parseDouble(torders.getDueamount())*0.3);
				}else{//旅行商10%
					penalty = Math.ceil(Double.parseDouble(torders.getDueamount())*0.1);
				}
			}else {
				penalty = 0.0;
			}
			torders.setPenalty(penalty);
			map.put("penalty", penalty);
			map.put("dueamount", torders.getDueamount());
			return BackResult.ok(map);
		}
	}
	
	public static long getDatePoor(Date endDate, Date nowDate) {
		 
	    long nh = 1000 * 60 * 60;
	    // 获得两个时间的毫秒时间差异
	    long diff = endDate.getTime() - nowDate.getTime();
	    // 计算差多少小时
	    long hour = diff / nh ;
	    return hour;
	}
	//删除订单
	public BackResult del(String orderid) {
		try {
			int result = tOrdersService.delOrder(orderid);
			if(result>0) {
				return BackResult.build("200", "删除订单成功");
			} else {
				return BackResult.build("400", "删除订单失败");
			}
		} catch (Exception e) {
			return BackResult.build("400", "系统繁忙，稍后再试");
		}
	}
	
	public BackResult backMoney(TOrders orders, HttpServletRequest request, HttpServletResponse response){
		TOrders torders = fRealscheService.getOrders(orders.getOrderid());
		// ==========>>数据校验
		List<String> messages = Lists.newArrayList(); // 消息
		boolean sendSms = false; // 是否发送短信
		if(messages.isEmpty()) {
			TPayinfo payinfo = torders.getPayinfo();
			if(payinfo!=null && payinfo.getDiscountid() != null){
				Map<String,Object> result = fRealscheService.proCmptReturn(orders);
				Integer returnflag = (Integer) result.get("returnflag");
				if(returnflag!=null&&returnflag==0){
					String payway = torders.getPayway();
					//批次号，必填，格式：当天日期[8位]+序列号[3至24位]，如：201603081000001
					String batch_no = new SimpleDateFormat("yyyyMMdd").format(new Date())+UUID.randomUUID().toString().replace("-", "").substring(0, 16);
					//退款笔数，必填，参数detail_data的值中，“#”字符出现的数量加1，最大支持1000笔（即“#”字符出现的数量999个）
					String batch_num = "1";
					Double money = (Double) result.get("returnmoney");
					//退款详细数据，必填，格式（支付宝交易号^退款金额^备注），多笔请用#隔开
					String detail_data = payinfo.getFlowno() // 流水号就是支付宝单号
							+"^"+money+"^"
							+torders.getPurchasenum()+","+torders.getChildnum(); // 退款数量
					if(payway.equals(TOrders.PAY_WAY_ALIPAY)){ // 支付宝支付
						String refund_date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
						try {
							RefundFastpayByPlatformNopwdReq req = new RefundFastpayByPlatformNopwdReq(batch_no, refund_date, batch_num, detail_data);
							new RefundFastpayByPlatformNopwdApi().execute(req, request, response);
							// 保存退款信息
							TOrdersOut orderOut = new TOrdersOut();
							orderOut.setOrderid(Integer.parseInt(torders.getOrderid()));
							orderOut.setBatchNo(batch_no);
							orderOut.setOutnum(Integer.parseInt(torders.getPurchasenum()));
							orderOut.setRtnmoney(money);
							orderOut.setOutchildnum(Integer.parseInt(torders.getChildnum()==null?"0":torders.getChildnum()));
							orderOut.setNotifyed(TOrdersOut.NOTIFED_NO);
							orderOut.setOutuserid(UserUtils.getUser().getId());
							orderOut.setRtnstatus(TOrdersOut.RTN_STATUS_FAIL);
							tOrdersOutService.save(orderOut);
							fRealscheService.proConfirmRtn(batch_no);
							messages.add("支付宝退票请求成功！");
							sendSms = true;
						} catch (Exception e) {
							messages.add("请求退款异常！");
							return BackResult.build("200", messages.get(0));
						}
					}
					if(payway.equals(TOrders.PAY_WAY_WXPAY)){ // 微信支付
						String out_trade_no = "";
						for(int i=0;i<32-orders.getOrderid().length();i++){ // 补齐32位字符串
							out_trade_no+="0";
						}
						int moneyint = (int)(money*100);
						out_trade_no+=torders.getOrderid();
						RefundReqData refundReqData = new RefundReqData(""//payinfo.getFlowno()
								, out_trade_no, ""
								, batch_no
								, (int)(Double.valueOf(torders.getDueamount())*100)
								, moneyint
								, Configure.getMchid()
								, "CNY");
						try {
							if(moneyint != 0){
								String responseString = WXPay.requestRefundService(refundReqData);
								logger.debug("微信退款返回信息：{}",responseString);
							}
							// 保存退款信息
							TOrdersOut orderOut = new TOrdersOut();
							orderOut.setOrderid(Integer.parseInt(torders.getOrderid()));
							orderOut.setBatchNo(batch_no);
							orderOut.setOutnum(Integer.parseInt(torders.getPurchasenum()));
							orderOut.setRtnmoney(money);
							orderOut.setOutchildnum(Integer.parseInt(torders.getChildnum()==null?"0":torders.getChildnum()));
							orderOut.setNotifyed(TOrdersOut.NOTIFED_NO);
							orderOut.setOutuserid(UserUtils.getUser().getId());
							orderOut.setRtnstatus(TOrdersOut.RTN_STATUS_FAIL);
							tOrdersOutService.save(orderOut);
							fRealscheService.proConfirmRtn(batch_no);
							if(moneyint == 0){
								messages.add("收取手续费后，可退费用为0元！");
							} else {
								messages.add("微信退票请求成功！");
							}
							sendSms = true;
						} catch (Exception e) {
							logger.debug("微信退票异常信息", e);
							messages.add("请求退款异常！");
							return BackResult.build("200", messages.get(0));
						}
					}
				} else {
					messages.add((String) result.get("returnmsg"));
				}
			} else {
				messages.add("订单暂未生效！");
				return BackResult.build("400", messages.get(0));
			}
		}
		if (TOrders.ORDER_TYPE_AIR_SHARE.equals(torders.getOrdertype())||TOrders.ORDER_TYPE_TRAVEL_SHARE.equals(torders.getOrdertype())) {
			//AA拼车退单成功,还需要修改拼车产品的已售出数量
			//1:根据shareid查询shareproduct
			String shareid = torders.getShareid();
			Integer paycount = torders.getPaycount();
			ShareRentproduct shareRentproduct = shareProductService.getInfo(shareid);
			//2:修改
			int newcount = shareRentproduct.getCurrentsell() - paycount;
			shareProductService.updateSellAmount(shareid, newcount+"");
		}
		// 订车人申请退单成功后，收到平台短信
		if(sendSms){
			Sms sms = new Sms();
			sms.setMobile(torders.getPayertel());
			sms.setContent("【霞客约车】您购买的由"+torders.getOffice().getName()+"提供的用车订单（"+torders.getOrderid()+"）已取消，我们将根据预订规则将相应款项在3个工作日内返回您的支付账户。");
			try {
				SmsApi.sendSms(sms);
				return BackResult.ok(true);
			} catch (Exception e) {
			}
		}
		return BackResult.build("400", messages.get(0));
	}
}
